<?php
/**
 * Created by PhpStorm.
 * User: lance
 * Date: 2017/10/26
 * Time: 13:59
 */

namespace app\customer\admin;

use app\admin\controller\Admin;
use app\common\builder\ZBuilder;
use app\common\log\addRole\CustomerAdd;
use app\common\log\distributeRole\DistributeCustomer;
use app\customer\model\Customer;
use encoding\libs\Encoding;
use php_excel\libs\Excel;
use think\Db;

/**
 * 客户资料导入新增
 * Class Import
 * @package app\customer\admin
 */
class Import extends Admin
{
    private $i_uid;
    private $i_role;
    private $a_userInfo;

    public function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
        $this->i_uid = session('user_auth.uid');
        $this->i_role = session('user_auth.role');

    }

    public function index()
    {
        return ZBuilder::make('form')->fetch();
    }

    /**
     * 导入客户资料
     * @return mixed
     */
    public function importCustomer()
    {
        if (request()->isPost()):
            set_time_limit(0);
            $i_fileId = input('file');
            $s_path = 'public/' . Db::name('admin_attachment')->where('id', $i_fileId)->value('path');
            //step1 获取excel数据
            $o_excel = new Excel();
            if (!is_file($s_path)):
                $this->error("请上传客户资料文件");
            endif;
            $a_data = $o_excel->import($s_path);
            array_shift($a_data);//去除表头
            //step2 组织数据
            $a_info = config('customer_info');
            $a_fields = array_map(function ($a_item) {
                return $a_item[1];
            }, $a_info);
            //去掉隐藏的id
            array_shift($a_fields);
            //step3 插入数据与记录日志
            $o_cus = new \app\customer\model\Customer();

            $i_sucNum = 0;//正确处理的客户人数
            $i_updateNum = 0;//成功更新人数
            $i_failNum = 0;//错误处理的客户人数
            $i_fUpdateNum = 0;//成功更新人数

            foreach ($a_data[0] as $i_key => $a_value):
                //身份证为空跳过
                if (empty($a_value[3])):
                    continue;
                endif;
                //身份证位数科学计数法转换为字符串
                if (strstr($a_value[3], 'E') && is_float($a_value[3])):
                    $a_value[3] = number_format($a_value[3], 0, '', '');
                endif;
                try {
                    Db::startTrans();
                    if (count($a_fields) !== count($a_value)):
                        $this->error("请按照上传文件内容格式上传正确的客户资料");
                    endif;
                    $a_data = array_combine($a_fields, $a_value);
                    //新增客户
                    $this->a_userInfo = $a_data;
                    $o_validate = validate('Customer');
                    if ($o_validate->check($a_data) === FALSE):
                        $this->error('客户' . $a_data['name'] . ' ' . $o_validate->getError());
                    endif;
                    $a_tmp = $this->isExist();
                    $i_id = $a_tmp['id'];
                    $i_managerId = $a_tmp['manager_id'];
                    if ($i_id):
                        //更新资料,不允许更新证件号码
                        if ($o_cus->where('id', $i_id)->field('cert_number', true)->update($a_data) === false):
                            throw new CustomerException("更新第" . ($i_key + 1) . "个客户失败");
                        endif;
                    else:
                        //插入资料
                        if (!$o_cus->insert($a_data)):
                            throw new CustomerException("新增第" . ($i_key + 1) . "个客户失败");
                        endif;
                    endif;
                    //判断用户角色如果是客户经理(role_id = 3)且原客户不存在客户经理进行用户自动分配
                    $i_customerId = $i_id ?: $o_cus->getLastInsID();
                    if ($this->i_role == 3 && !$i_managerId):
                        $o_disCustomer = new DistributeCustomer([
                            'manager_id' => Db::name('manager')->where('id', UID)->value('role_id') ?: 0,
                            'customer_id' => $i_customerId,
                            'message' => '系统自动分配客户',
                        ]);
                        $m_rsl = $o_disCustomer->disOne();
                        if ($m_rsl !== true):
                            throw new CustomerException($m_rsl);
                        endif;
                    endif;
                    Db::commit();
                    //记录成功日志
                    $a_logData = [
                        'role_id' => $i_customerId,
                        'type' => 2,//批量导入用户
                        'update' => $i_id ? true : false,
                        'status' => 1,
                        'error' => '',
                        'content' => json_encode($a_data)
                    ];
                    $o_obj = new CustomerAdd($a_logData);
                    $o_obj->addOne();
                    if ($i_id):
                        $i_updateNum++;
                    else:
                        $i_sucNum++;
                    endif;
                } catch (CustomerException $e) {
                    Db::rollback();
                    if ($i_id):
                        $i_fUpdateNum++;
                    else:
                        $i_failNum++;
                    endif;
                    //记录失败日志
                    $a_logData = [
                        'role_id' => 0,
                        'status' => 0,
                        'update' => $i_id ? true : false,
                        'type' => 2,//批量导入用户
                        'error' => $e->getMessage(),
                        'content' => json_encode($a_data)
                    ];
                    $o_obj = new CustomerAdd($a_logData);
                    $o_obj->addOne();
                }
            endforeach;
            $s_tips = <<<EOT
            添加{$i_sucNum}人，失败{$i_failNum}人。更新{$i_updateNum}人，失败{$i_fUpdateNum}人。具体可查看客户日志。
EOT;

            $this->success($s_tips, '', '', 6);
        else:
            $s_tips = <<<EOT
1.支持导入格式xls,xlsx
2.客户资料依次为，姓名、性别、证件类型、生日（1950-12-03）、联系电话、其他号码、行业、职业、性格、兴趣特长,可参考创建测试用户资料
EOT;

            return ZBuilder::make('form')
                ->setPageTips($s_tips)
                ->addFile('file', '客户资料文件', '仅支持xls,xlsx两种格式', '', '', 'xls,xlsx')
                ->fetch();
        endif;
    }

    /**
     * 手动添加客户
     */
    public function add()
    {
        if (request()->isAjax()):
            $this->a_userInfo = input('');
            if ($this->isExist()):
                $this->error("证件号:" . $this->a_userInfo['cert_number'] . '存在！');
            endif;
            $o_validate = Validate('Customer');
            //验证数据
            if ($o_validate->check(input('')) === FALSE):
                $this->error($o_validate->getError());
            endif;
            //保存数据
            $o_model = new Customer;
            Db::startTrans();
            try {
                //step1 添加用户
                if (!$o_model->insert(input(''))):
                    throw new CustomerException('添加客户失败！');
                endif;
                $i_customerId = $o_model->getLastInsID();
                //step2 判断用户角色如果是客户经理(role_id = 3)进行用户自动分配
                if ($this->i_role == 3):
                    $o_disCustomer = new DistributeCustomer([
                        'manager_id' => Db::name('admin_user')->where('id', UID)->value('role_id') ?: 0,
                        'customer_id' => $i_customerId,
                        'message' => '系统自动分配客户',
                    ]);
                    $m_rsl = $o_disCustomer->disOne();
                    if ($m_rsl !== true):
                        throw new CustomerException($m_rsl);
                    endif;
                endif;
                Db::commit();
                //step3 记录用户添加日志
                $a_logData = [
                    'role_id' => $i_customerId,
                    'status' => 1,
                    'type' => 1,//添加用户
                    'error' => '',
                    'content' => json_encode(input(''))
                ];
                $o_obj = new CustomerAdd($a_logData);
                $o_obj->addOne();
                $this->success("添加成功!");
            } catch (CustomerException $e) {
                //step4 记录用户添加失败错误日志
                Db::rollback();
                $a_logData = [
                    'role_id' => 0,
                    'status' => 0,
                    'type' => 1,//添加用户
                    'error' => $e->getMessage(),
                    'content' => json_encode(input(''))
                ];
                $o_obj = new CustomerAdd($a_logData);
                $o_obj->addOne();
                $this->error($e->getErrorMsg());
            }
        else:
            //提示信息
            $s_tips = <<<EOT
1.客户经理手动添加的客户直接被分配到该经理。
EOT;

            return ZBuilder::make('form')
                ->setPageTips($s_tips)
                ->addFormItems(Config('customer_info'))
                ->fetch();
        endif;
    }

    /**
     * 根据件号码判断好似否存在相同客户信息
     * 成功返回客户Id
     */
    private function isExist()
    {
        $s_certNumber = $this->a_userInfo['cert_number'];
        return Db::name('customer')->where('cert_number', $s_certNumber)->field('id,manager_id')->find();
    }
}